home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / nrs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  4.9 KB  |  211 lines

  1. /* This module implements the serial line framing method used by
  2.  * net/rom nodes.  This allows the net/rom software to talk to
  3.  * an actual net/rom over its serial interface, which is useful
  4.  * if we want to do packet switching for multi-line wormholes.
  5.  * Dan Frank, W9NK
  6.  */
  7. #include <stdio.h>
  8. #include "global.h"
  9. #include "config.h"
  10. #ifdef NRS
  11. #include "mbuf.h"
  12. #include "iface.h"
  13. #include "pktdrvr.h"
  14. #include "ax25.h"
  15. #include "nrs.h"
  16. #include "asy.h"
  17. #include "trace.h"
  18. #include "commands.h"
  19.  
  20. static struct mbuf * near nrs_encode __ARGS((struct mbuf *bp));
  21. static struct mbuf * near nrs_decode __ARGS((int dev,char c));
  22.  
  23. /* control structures, sort of overlayed on async control blocks */
  24. struct nrs Nrs[ASY_MAX];
  25.  
  26. /* Send a raw net/rom serial frame */
  27. int
  28. nrs_raw(iface,bp)
  29. struct iface *iface;
  30. struct mbuf *bp;
  31. {
  32.     struct mbuf *bp1;
  33.  
  34.     if((bp1 = nrs_encode(bp)) == NULLBUF){
  35.         free_p(bp);
  36.         return -1;
  37.     }
  38.     dump(iface,IF_TRACE_OUT,CL_AX25,bp) ;
  39.  
  40.     return Nrs[iface->xdev].send(iface->dev,bp1);
  41. }
  42.  
  43. /* Encode a packet in net/rom serial format */
  44. static struct mbuf * near
  45. nrs_encode(bp)
  46. struct mbuf *bp;
  47. {
  48.     struct mbuf *lbp;    /* Mbuf containing line-ready packet */
  49.     register char *cp;
  50.     int c;
  51.     unsigned char csum = 0 ;
  52.  
  53.     /* Allocate output mbuf that's twice as long as the packet.
  54.      * This is a worst-case guess (consider a packet full of STX's!)
  55.      * Add five bytes for STX, ETX, checksum, and two nulls.
  56.      */
  57.     lbp = ambufw((int16)(2*len_p(bp) + 5));
  58.     cp = lbp->data;
  59.  
  60.     *cp++ = STX ;
  61.  
  62.     /* Copy input to output, escaping special characters */
  63.     while((c = PULLCHAR(&bp)) != -1){
  64.         switch(c){
  65.         case STX:
  66.         case ETX:
  67.         case DLE:
  68.             *cp++ = DLE;
  69.             /* notice drop through to default */
  70.         default:
  71.             *cp++ = c;
  72.         }
  73.         csum += c;
  74.     }
  75.     *cp++ = ETX;
  76.     *cp++ = csum ;
  77.     *cp++ = NUL ;
  78.     *cp++ = NUL ;
  79.     
  80.     lbp->cnt = cp - lbp->data;
  81.     return lbp;
  82. }
  83.  
  84. /* Process incoming bytes in net/rom serial format
  85.  * When a buffer is complete, return it; otherwise NULLBUF
  86.  */
  87. static struct mbuf * near
  88. nrs_decode(dev,c)
  89. int dev;    /* net/rom unit number */
  90. char c;        /* Incoming character */
  91. {
  92.     struct mbuf *bp;
  93.     struct nrs *sp;
  94.  
  95.     sp = &Nrs[dev];
  96.     switch(sp->state) {
  97.         case NRS_INTER:
  98.             if (uchar(c) == STX) {    /* look for start of frame */
  99.                 sp->state = NRS_INPACK ;    /* we're in a packet */
  100.                 sp->csum = 0 ;                /* reset checksum */
  101.             }
  102.             return NULLBUF ;
  103.         case NRS_CSUM:
  104.             bp = sp->rbp ;
  105.             sp->rbp = NULLBUF ;
  106.             sp->rcnt = 0 ;
  107.             sp->state = NRS_INTER ;    /* go back to inter-packet state */
  108.             if (sp->csum == uchar(c)) {
  109.                 sp->packets++ ;
  110.             } else {
  111.                 free_p(bp) ;    /* drop packet with bad checksum */
  112.                 bp = NULLBUF;
  113.                 sp->errors++ ;    /* increment error count */
  114.             }
  115.             return bp ;
  116.         case NRS_ESCAPE:
  117.             sp->state = NRS_INPACK ;    /* end of escape */
  118.             break ;            /* this will drop through to char processing */
  119.         case NRS_INPACK:
  120.             switch (uchar(c)) {
  121.             /* If we see an STX in a packet, assume that previous */
  122.             /* packet was trashed, and start a new packet */
  123.             case STX:
  124.                 free_p(sp->rbp) ;
  125.                 sp->rbp = NULLBUF ;
  126.                 sp->rcnt = 0 ;
  127.                 sp->csum = 0 ;
  128.                 sp->errors++ ;
  129.                 return NULLBUF ;
  130.             case ETX:
  131.                 sp->state = NRS_CSUM ;    /* look for checksum */
  132.                 return NULLBUF ;
  133.             case DLE:
  134.                 sp->state = NRS_ESCAPE ;
  135.                 return NULLBUF ;
  136.             }
  137.     }
  138.     /* If we get to here, it's with a character that's part of the packet.
  139.      * Make sure there's space for it.
  140.      */
  141.     if(sp->rbp == NULLBUF){
  142.         /* Allocate first mbuf for new packet */
  143.         sp->rbp1 = sp->rbp = ambufw(NRS_ALLOC);
  144.         sp->rcp = sp->rbp->data;
  145.     } else if(sp->rbp1->cnt == NRS_ALLOC){
  146.         /* Current mbuf is full; link in another */
  147.         sp->rbp1->next = ambufw(NRS_ALLOC);
  148.         sp->rbp1 = sp->rbp1->next;
  149.         sp->rcp = sp->rbp1->data;
  150.     }
  151.     /* Store the character, increment fragment and total
  152.      * byte counts
  153.      */
  154.     *sp->rcp++ = c;
  155.     sp->rbp1->cnt++;
  156.     sp->rcnt++;
  157.     sp->csum += uchar(c) ;    /* add to checksum */
  158.     return NULLBUF;
  159. }
  160.  
  161. /* Process net/rom serial line I/O */
  162. void
  163. nrs_recv(dev,v1,v2)
  164. int dev;
  165. void *v1;
  166. void *v2;
  167. {
  168.     char c;
  169.     struct mbuf *bp,*nbp;
  170.     struct phdr phdr;
  171.  
  172.     /* Process any pending input */
  173.     for(;;){
  174.         c = Nrs[dev].get(Nrs[dev].iface->dev);
  175.         if((bp = nrs_decode(dev,c)) == NULLBUF)
  176.             continue;
  177.         if((nbp = pushdown(bp,sizeof(phdr))) == NULLBUF){
  178.             free_p(bp);
  179.             continue;
  180.         }
  181.         phdr.iface = Nrs[dev].iface;
  182.         phdr.type = CL_AX25;
  183.         memcpy(&nbp->data[0],(char *)&phdr,sizeof(phdr));
  184.         enqueue(&Hopper,nbp);
  185.     }
  186.  
  187. }
  188.  
  189. /* donrstat:  display status of active net/rom serial interfaces */
  190. int
  191. donrstat(argc,argv,p)
  192. int argc ;
  193. char *argv[] ;
  194. void *p;
  195. {
  196.     struct nrs *np ;
  197.     int i ;
  198.  
  199.     tputs("Interface   RcvB  NumReceived  CSumErrors\n") ;
  200.  
  201.     for (i = 0, np = Nrs ; i < ASY_MAX ; i++, np++)
  202.         if (np->iface != NULLIF)
  203.             tprintf(" %8s   %4d   %10lu  %10lu\n",
  204.                 np->iface->name, np->rcnt,
  205.                 np->packets, np->errors);
  206.  
  207.     return 0 ;
  208. }
  209.  
  210. #endif /* NRS */
  211.